package com.logic.landseaserver.service.impl;

import java.text.DecimalFormat;
import java.text.Format;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.logic.landseaserver.domain.*;
import com.logic.landseaserver.persistence.read.*;
import com.logic.landseaserver.ws.dto.*;
import com.logic.system.service.IConfigurationService;
import com.logic.system.service.impl.ConfigurationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.logic.common.domain.Code;
import com.logic.common.exception.BusinessException;
import com.logic.common.security.SecurityUtils;
import com.logic.common.util.PagingTool;
import com.logic.common.util.QueryCriteria;
import com.logic.common.util.QueryUtil;
import com.logic.common.ws.dto.system.UserDTO;
import com.logic.landseaserver.common.LandeaConstants;
import com.logic.landseaserver.common.LandseaErrorMessageEnum;
import com.logic.landseaserver.common.config.SendMsgConfiguration;
import com.logic.landseaserver.common.enums.OffRentReasonEnum;
import com.logic.landseaserver.common.enums.RefundTypeEnum;
import com.logic.landseaserver.common.enums.SystemCodeEnum;
import com.logic.landseaserver.common.exception.LandseaException;
import com.logic.landseaserver.common.util.DateUtil;
import com.logic.landseaserver.common.util.LandSeaUtil;
import com.logic.landseaserver.common.util.SMSUtil;
import com.logic.landseaserver.models.prepayment.service.PrepaymentService;
import com.logic.landseaserver.persistence.write.OffrentContactWriteMapper;
import com.logic.landseaserver.persistence.write.RefundLogWriteMapper;
import com.logic.landseaserver.persistence.write.RefundWriteMapper;
import com.logic.landseaserver.service.IBillService;
import com.logic.landseaserver.service.IOffRent;
import com.logic.landseaserver.service.IOffrentPreBill;
import com.logic.landseaserver.service.IRefund;
import com.logic.landseaserver.ws.response.PreBillResp;
import com.logic.system.domain.Role;
import com.logic.system.domain.SystemFile;
import com.logic.system.domain.User;
import com.logic.system.domain.UserProject;
import com.logic.system.persistence.read.RoleReadMapper;
import com.logic.system.persistence.read.UserReadMapper;
import com.logic.system.service.ICodeService;
import com.logic.system.service.IUserService;
import com.logic.system.service.impl.FileService;
import com.logic.system.ws.dto.UserRoleDTO;

/**
 *
 * 项目名称：system-server</br>
 * 类名称：OffRentServiceImpl</br>
 * 类描述：</br>
 * 创建人：tony</br>
 * 创建时间：2017年8月14日 下午4:27:12</br>
 * 
 * @version 1.0
 *         
 */

@Service
public class RefundServiceImpl implements IRefund
{
    @Autowired
    private SendMsgConfiguration sendMsgConfiguration;
    
    @Autowired
    private ContractReadMapper contractReadMapper;

    @Autowired
    private RefundReadMapper refundReadMapper;
    
    @Autowired
    private RefundWriteMapper refundWriteMapper;
    
    @Autowired
    private DepositReadMapper depositReadMapper;
    
    @Autowired
    private ProjectReadMapper projectReadMapper;
    
    @Autowired
    private RoleReadMapper roleReadMapper;
    
    @Autowired
    private RefundLogWriteMapper refundLogWriteMapper;
    
    @Autowired
    private RefundLogReadMapper refundLogReadMapper;
    
    @Autowired
    private UserReadMapper userReadMapper;

    @Autowired
    private OffrentContactReadMapper offrentContactReadMapper;

    @Autowired
    private OffrentContactWriteMapper offrentContactWriteMapper;

    @Autowired
    private OffRentReadMapper offRentReadMapper;

    @Autowired
    private FileService fileService;

    @Autowired
    private IBillService billService;

    @Autowired
    private ICodeService codeService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IOffrentPreBill offrentPreBillService;
    
    @Autowired
    private PrepaymentService prepaymentService;

    @Autowired
    private IConfigurationService configurationService;

    @Autowired
    private IOffRent offRentServiceImpl;
    
    @Autowired
    private IOffRent offRent;

    private static final Logger LOG = LoggerFactory.getLogger(RefundServiceImpl.class);

    private static final ArrayList<String> leaderList = new ArrayList<String>(){
        {
            //0802 区域经理-总部运营负责人-总部账务会计（分区域）-项目出纳
            //0417 区域运营经理-总部财务主管-项目财务出纳
            //live
            add("CTKPR");   //区域运营经理
            //0417 简化审批流程 去掉总部运营负责人 流程
            add("HEADKPR");    //总部运营负责人
          //  add("FINANCIAL");    //总部财务负责人
            add("CWCN");    //总部财务主管
            add("TREASURER"); //项目财务出纳
            //beta
            /*
            add("CTKPR");   //区域运营经理
            add("NASA");    //总部运营负责人
            add("ADAD");    //总部财务负责人
            add("CWCN");    //总部财务主管
            add("Treasurer"); //项目财务出纳*/
        }      
    };

    private static final ArrayList<String> queryLeaderList = new ArrayList<String>(){
        {
            //live
            add("CTKPR");   //区域运营经理
            add("HEADKPR");    //总部运营负责人
            add("FINANCIAL");    //总部财务负责人
            add("CWCN");    //总部财务主管
            add("TREASURER"); //项目财务出纳
        }
    };
    private static final ArrayList<String> hourseKeepList = new ArrayList<String>(){
        {
            add("SPKPR");   //店长
            add("HSKPR");    //管家
        }
    };
    private static final ArrayList<String> supperList = new ArrayList<String>(){
        {
            add("ROOT");   //超级管理员
            add("DEVDIRECTOR");    //运营管理员
        }
    };

    //上面角色的   Role  list
    private static List<Role> leaderRoleList = null;
    
    
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = {LandseaException.class,Exception.class})
    public HashMap<String, Object> addOrEditRefund(RefundReqDTO refunddto) throws LandseaException,BusinessException
    {
        Refund refund = transRefundReqDTOtoRefund(refunddto);
        Integer userId = SecurityUtils.getCurrentLogin().getUserId();
        validateDate(refunddto);
        Integer typeId = refund.getType();
        Integer roomId = null;
        Integer projectId = null;
        
        // 是否为转租的退款
        boolean isChangeRent = false;
        // 转租合同
        Contract changeRentContract = null;
        
        //获取房间id
        if(SystemCodeEnum.REFUND_BUSIS_DIPOSIT.getCode().equals(String.valueOf(typeId))){ //预定
            depositValidateDate(refund);
            Integer depositId = refund.getObjectId();
            Deposit deposit = depositReadMapper.selectByPrimaryKey(depositId);
            if(deposit==null){
                throw LandseaException.createException(LandseaErrorMessageEnum.DEPOSIT_IS_NULL); 
            }
            roomId = deposit.getRoomId();
            projectId = deposit.getPrjId();
        }else if(SystemCodeEnum.REFUND_BUSIS_CONTRACT.getCode().equals(String.valueOf(typeId))){//合同
            contractValidateDate(refund);
            Integer contractId = refund.getObjectId();
            Contract contract = contractReadMapper.selectByPrimaryKey(contractId);
            if(contract==null){
                throw LandseaException.createException(LandseaErrorMessageEnum.CONTRACT_IS_NULL); 
            }
            //如果是转租合同 B合同未付款之前A不允许提交退款申请
            if(contract.getRentStatus()!=null){
                if(contract.getRentStatus().equals(LandeaConstants.ReRentType.CHANGE)){
                    
                    isChangeRent = true;
                    changeRentContract = contract;
                    
                    //查询转租合同
                    ContractDTO reRentContract = contractReadMapper.queryReRentContractDetail(contractId);
                    if(reRentContract!=null){
                        //查询首付款是否已支付
                        if(reRentContract.getPayTime()==null){
                            throw LandseaException.createException(LandseaErrorMessageEnum.CHANGE_CONTRACTB_ISNOTPAY_NTEXSIT_REFUND);
                        }
                    }/*else{
                        throw LandseaException.createException(LandseaErrorMessageEnum.CHANGE_CONTRACTB_IS_NTEXSIT_REFUND);
                    }*/
                }
            }
            roomId = contract.getRoomId();
            projectId = contract.getProjectId();
        }
        if(roomId == null){
            throw LandseaException.createException(LandseaErrorMessageEnum.ROOM_IS_NULL); 
        }
        if(projectId == null){
            throw LandseaException.createException(LandseaErrorMessageEnum.PRJ_IS_NULL); 
        }
        refund.setPrjId(projectId);
        refund.updateCommonInfo(userId);
        HashMap<String,Object> result = new HashMap<String,Object>();
        if (exiteOffRent(refund)){ // 存在 --- 更新
            refundWriteMapper.updateByObjectIdTypeSelective(refund);
        }else{ // 不存在 -- 插入
//            //往房间添加退租标签
//            Room room = new Room();
//            room.setId(roomId);
//            room.setOffrentStatus(true);
//            roomWriteMapper.updateByPrimaryKeySelective(room);
//          
            //生成退款编码
            Project prj = projectReadMapper.selectByPrimaryKey(projectId);
            if(prj == null){
                throw LandseaException.createException(LandseaErrorMessageEnum.PRJ_IS_NULL); 
            }
            String prjCode = prj.getPrjCode();
            Integer maxnum = refundReadMapper.getMaxRefundCode(prjCode);
            if (maxnum == null) {
                maxnum = 0;
            } else {
                maxnum = maxnum + 1;
            }
            Format f1 = new DecimalFormat("000000");
            String refundCode = prjCode + f1.format(maxnum).toString();
            refund.setRefundCode(refundCode);
            refund.setApplyUser(SecurityUtils.getCurrentLogin().getUserId());   
            String code = leaderList.get(0);
            Role role = roleReadMapper.getRoleByCode(code);
            if(null==role){
                throw LandseaException.createException(LandseaErrorMessageEnum.ROLE_IS_NULL); 
            }
            refund.setCurrentRoleId(role.getId());
            refund.setStatus(SystemCodeEnum.REFUND_STATUS_ON.getCode());
            refund.setApplyDate(new Date());
            refundWriteMapper.insertSelective(refund);
            
            //查询角色为code且具有project管理权限的人的姓名和手机号
            List<PersonInfoDTO> phoneList = refundReadMapper.getPersonInfoByPrjAndRole(projectId , code);
            HashMap<String,String> map = new HashMap<String,String>();
            map.put("refundCode", refund.getRefundCode());
            //发送消息
            try{
                sentMag(phoneList,map);
            }catch (Exception e){
                LOG.error("apply renfund send msg error:"+e);
            }
            //添加一条确认日志
            User hourseUser = null;
            try {
                hourseUser = (User) userService.get(userId);
            } catch (BusinessException e) {
                throw LandseaException.createException(LandseaErrorMessageEnum.NO_USER);
            }
            RefundLog refundlog = new RefundLog();
            refundlog.setUserId(userId);
            if(hourseUser!=null){
                List<Role> roleList = hourseUser.getRoleList();
                if(roleList!=null){
                    for(Role r:roleList){
                        if(r.getCode().equals(hourseKeepList.get(0))){
                            refundlog.setRoleId(r.getId());
                            break;
                        }
                        if(r.getCode().equals(hourseKeepList.get(1))){
                            refundlog.setRoleId(r.getId());
                        }
                    }
                }
            }
            refundlog.setRefundId(refund.getId());
            refundlog.setCheckDate(new Date());
            refundlog.setComment("提交");
            refundlog.updateCommonInfo(userId);
            refundLogWriteMapper.insertSelective(refundlog);
        }
        
        // 如果是转租，要清理余额（清理冻结金额归零）
        if (isChangeRent)
        {
            prepaymentService.changeRentClearFrozenMoney(changeRentContract.getUserId(), changeRentContract.getRoomId());
        }
        
        result.put("status", 0);
        return result;
    }
    
    private Refund transRefundReqDTOtoRefund(RefundReqDTO refunddto) throws LandseaException, BusinessException {
        Refund refund = new Refund();
        refund.setComment(refunddto.getComment());
        refund.setFileId(refunddto.getFileId());
        refund.setObjectId(refunddto.getObjectId());
        refund.setRefundAmount(refunddto.getRefundAmount());
        refund.setType(refunddto.getType());
        refund.setBankBrname(refunddto.getBankBrname());
        refund.setBankName(refunddto.getBankName());
        refund.setCardNo(refunddto.getCardNo());
        refund.setCardUserName(refunddto.getCardUserName());
        if(refunddto.getType()==1){
            refund.setRefundType(RefundTypeEnum._RFDTYPE1.getCode());
        }else{
            refund.setRefundType(RefundTypeEnum._RFDTYPE2.getCode());
            //check是强行退房还是正常退房
            //查询退房申请记录
            String reasonCode = "";
            HashMap queryMap = new HashMap();
            queryMap.put("contractId",refunddto.getObjectId());
            queryMap.put("offrentType", LandeaConstants.ReRentType.OFFRENT);
            List<OffRentDTO> applyList = offRentReadMapper.selectByCondt(queryMap);
            if(applyList.size()>0){
                OffRentDTO offDto = applyList.get(0);
                reasonCode = offDto.getOffrentReason();
            }
            if(!StringUtils.isEmpty(reasonCode)){
                if(reasonCode.equals(OffRentReasonEnum._OFRTRS14.getCode())){
                    refund.setRefundType(RefundTypeEnum._RFDTYPE3.getCode());
                    //强行退房将姓名放置 同步退房申请
                    //  OffRentContractDTO offRentcontractDTO = offRentServiceImpl.getOffRent(refunddto.getObjectId(),null);
                    OffRentDTO offRentDTO =  offRentReadMapper.selectByCId(refunddto.getObjectId());
                    if(offRentDTO!=null && !StringUtils.isEmpty(offRentDTO.getCardUserName() )){
                        refund.setBankBrname(offRentDTO.getBankBrname());
                        refund.setBankName(offRentDTO.getBankName());
                        refund.setCardNo(offRentDTO.getCardNo());
                        refund.setCardUserName(offRentDTO.getCardUserName());
                    }else{
                        ContractDTO contractOff = contractReadMapper.queryContractDetail(refunddto.getObjectId());
                        if(contractOff!=null){
                            refund.setCardUserName(contractOff.getCertificatesName());
                        }
                    }

                }
            }
            //如果是退房，则需查看结算单的退房类型
            PreOffrentBill preOffrentBill = offrentPreBillService.queryPreBillByContractId(refunddto.getObjectId());
            if(preOffrentBill!=null){
                refund.setOffrentType(preOffrentBill.getOffrentType());
            }
        }
        return refund;
    }

    private void sentMag(List<PersonInfoDTO> pinfoList,HashMap<String,String> map)
    {
        Iterator<PersonInfoDTO> it =pinfoList.iterator();
        String code = map.get("refundCode");
        while(it.hasNext()){
            PersonInfoDTO pinfo = it.next();
            //${name}你好，您有一条退款申请${code}等待您的审批。
            
            String msg = " {'code':'"+code+"'}";
            String signName = configurationService.getStringValue(ConfigurationService.SEND_MSG_SIGN_NAME);
            SMSUtil.sendSms(sendMsgConfiguration.getRefundManagerMessageCode(), pinfo.getPhone() , msg,signName);
        }
    }
    
    private void sentMesgToRenter(String phone,HashMap<String,Object> map)
    {
        //${name}${gender}，您好：您的退款${money}元，即将汇入您尾号${fourlastnumber}的${bank}账户，到帐周期以您银行为准，请注意查收。如有问题，请致电400-8282-661。朗诗寓期待您的再次入住。
        //${name}您好！您的退款${money}元，即将汇入您尾号${fourlastnumber}的${bank}账户，到帐周期以您银行为准，请注意查收。如有问题，请致电400-8282-661。朗诗寓期待您的再次入住。
      //  String msg = " {'name':'"+map.get("name")+map.get("gender")+"','money':'"+map.get("money")+"','fourlastnumber':'"+map.get("fourlastnumber")+"','bank':'"+map.get("bank")+"'}";
        Double refundMy = LandSeaUtil.get2Double((Double) map.get("money"));
      //  String msg = " {'name':'"+map.get("name")+map.get("gender")+"','money':'"+Math.abs(refundMy)+"','fourlastnumber':'"+map.get("fourlastnumber")+"'}";
        String msg = " {'money':'"+Math.abs(refundMy)+"','fourlastnumber':'"+map.get("fourlastnumber")+"'}";
        String signName = configurationService.getStringValue(ConfigurationService.SEND_MSG_SIGN_NAME);
        SMSUtil.sendSms(sendMsgConfiguration.getRefundRenterMessageCode(), phone , msg,signName);
    }

    private boolean exiteOffRent(Refund refund) throws LandseaException
    {
        List<Refund> refundlist = refundReadMapper.selectByObjectIdAndType(refund);
        //if (refundlist.size() > 1){
            //throw LandseaException.createException(LandseaErrorMessageEnum.HAVE_MULTI_REFUND);
        //}
         if (refundlist.size() == 0){
            return false;
        }
        else{
            return true;
        }
    }

    private void validateDate(RefundReqDTO refunddto){
        
    }
    
    private void depositValidateDate(Refund refund){
    }
    
    private void contractValidateDate(Refund refund){
    }

    @Override
    public List<RefundDTO> getRefundList(QueryUtil queryUtil)
    {
        Integer userId = SecurityUtils.getCurrentLogin().getUserId();
        //获取当前用户权限下的项目和所有角色
        UserPrjRoleDTO dto = userReadMapper.getPrjsAndRole(userId);
        List<UserProject> uplist = dto.getUserProject();
        
        //遍历，获取所有项目id放入list  为了在sql中拼成in语句（或者foreach遍历）
        List<Integer> prjIdlist = new ArrayList<Integer>();
        for(UserProject up: uplist){
            Integer prjId = up.getPrjId();
            prjIdlist.add(prjId);
        }
        String selfRoleIdStr = "";  //自身角色id list
        
        // 1. 拼接自身所有角色为字符串   2.获取自身角色中最小的
        List<UserRoleDTO> roledto = dto.getUserRole();
        Integer minRoleId = null;
        Integer minIndex = null;
        Boolean issuper = false;
        Boolean isKeep = false;
        Boolean isLeader= false;
        List<Integer> leaderIdList = new ArrayList<Integer>();          //自身角色List，作用同上
        for(UserRoleDTO role:roledto){
            selfRoleIdStr = selfRoleIdStr + role.getRoleId()+",";
            //获取自身角色中权限最低的角色id
            Integer codeIndex = leaderList.indexOf(role.getCode());
            Integer superIndex = supperList.indexOf(role.getCode());
            Integer keepIndex = hourseKeepList.indexOf(role.getCode());
            //Integer codeIndex = queryLeaderList.indexOf(role.getCode());
            if(superIndex>=0){  //说明是supperList里的角色
                issuper = true;
            }
            if(keepIndex>=0){ //说明是hourseKeepList里的角色
                isKeep=true;
            }
            
            if(codeIndex>=0 ){   //说明该角色存在于leaderList
                isLeader = true;
                if(null==minRoleId){
                    minRoleId = role.getRoleId();
                    minIndex = codeIndex;
                }else{
                    if(minIndex>codeIndex){
                        minRoleId = role.getRoleId();
                        minIndex = codeIndex;
                    }
                }
            }
        }
        selfRoleIdStr = selfRoleIdStr.substring(0, selfRoleIdStr.length()-1);
        
        //如果是超级管理员则返回管理项目下的所有退款记录
        if(issuper){
            queryUtil.getParams().put("selfRoleIds", selfRoleIdStr);
            String aaa = prjIdlist.toString();
            aaa = aaa.substring(1, aaa.length()-1);
            queryUtil.getParams().put("prj", prjIdlist.size()==0?null:aaa);
            List<RefundDTO> dtoList = refundReadMapper.getSuperRefundList(queryUtil);
            for (RefundDTO refundDTO : dtoList)
            {
                String otherRemark = refundReadMapper.getApplyOffrentOtherRemark(refundDTO.getObjectId());
                refundDTO.setOtherRemark(otherRemark);
            }
            return dtoList;
        }
        
        //获取审批角色的所有id
        if(null==leaderRoleList){
            leaderRoleList = roleReadMapper.getRoleByCodeList(leaderList); 
        }
        
        for(String code: leaderList){
            for(Role roleDto :leaderRoleList){
                if(code.equals(roleDto.getCode()))
                leaderIdList.add(roleDto.getId());
            }
        }
        
        for(Integer terr: leaderIdList){
            LOG.info("leaderIdList is:"+terr);
        }
        //如果是店长或者管家
        List<Integer> idlist = new ArrayList<>();
        if(!isKeep || (isKeep && isLeader)){
            //获取比自身最小权限更高的所有角色（因为自己审批过的，待更高权限的人审批时，也可查看）
            idlist = leaderIdList.subList(leaderIdList.indexOf(minRoleId), leaderIdList.size());
            for(Integer terr : idlist){
                LOG.info("idlist is :"+terr);
            }
        }

        queryUtil.getParams().put("selfRoleIds", selfRoleIdStr);
        
        String aaa = prjIdlist.toString();
        aaa = aaa.substring(1, aaa.length()-1);
        
        String bbb = idlist.toString();
        bbb = bbb.substring(1, bbb.length()-1);
        bbb = bbb + ",-1";      //包含审批结束的退款信息
        
        queryUtil.getParams().put("prj", prjIdlist.size()==0?-1:aaa);

        queryUtil.getParams().put("showIdList", idlist.size()==0?null:bbb);

        List<RefundDTO> dtoList = refundReadMapper.getRefundList(queryUtil);
        for (RefundDTO refundDTO : dtoList)
        {
            if (1 == refundDTO.getType().intValue())
            {
                refundDTO.setOtherRemark(null);
            }
            else if (2 == refundDTO.getType().intValue())
            {
                String otherRemark = refundReadMapper.getApplyOffrentOtherRemark(refundDTO.getObjectId());
                refundDTO.setOtherRemark(otherRemark);
            }
        }
        return dtoList;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = {LandseaException.class,Exception.class})
    public HashMap<String, Object> confirmRefund(RefundLog refundlog) throws LandseaException, BusinessException {
        validateRefundLogParams(refundlog);
        HashMap<String, Object> result = new HashMap<String, Object>();
        //获取当前卡点
        Integer refundId = refundlog.getRefundId();
        Refund refund = refundReadMapper.selectByPrimaryKey(refundId);
        if(null==refund){
            throw LandseaException.createException(LandseaErrorMessageEnum.REFUND_IS_NULL); 
        }

        Integer currentUserId = refund.getCurrentRoleId();      //获取当前卡点角色的id
        if(-1==currentUserId){
            if(SystemCodeEnum.REFUND_STATUS_OVER.getCode().equals(refund.getStatus())){
                result.put("status", -1);
                result.put("msg", "此账单已审批结束");
                return result;
            }
        }
        //对当前登录用户权限进行检测
        validateCurrentLoginId(refund);
        Integer typeId = refund.getType();
        String renterPhone = null;
        String renterName = "";
        String renterGender = " ";
        String money = " ";
        Integer projectId = null;
        //获取房间id
        if(SystemCodeEnum.REFUND_BUSIS_DIPOSIT.getCode().equals(String.valueOf(typeId))){ //预定
//            depositValidateDate(refund);
            Integer depositId = refund.getObjectId();
            DepositDTO deposit = depositReadMapper.getDepositDetail(depositId);
            if(deposit==null){
                throw LandseaException.createException(LandseaErrorMessageEnum.DEPOSIT_IS_NULL); 
            }
            renterPhone = deposit.getCellPhone();
            projectId = deposit.getPrjId();
            renterName = deposit.getUserName();
            renterGender = deposit.getGender();
        }else if(SystemCodeEnum.REFUND_BUSIS_CONTRACT.getCode().equals(String.valueOf(typeId))){//合同
            contractValidateDate(refund);
            Integer contractId = refund.getObjectId();
            ContractDTO contract = contractReadMapper.queryContractDetail(contractId);
            if(contract==null){
                throw LandseaException.createException(LandseaErrorMessageEnum.CONTRACT_IS_NULL); 
            }
            renterPhone = contract.getCellphone();
            renterName = contract.getCertificatesName();
            renterGender = contract.getGender();
            projectId = contract.getProjectId();
        }
        if(renterPhone == null){
            throw LandseaException.createException(LandseaErrorMessageEnum.RENTER_PHONE_IS_NULL); 
        }
        if(projectId == null){
            throw LandseaException.createException(LandseaErrorMessageEnum.PRJ_IS_NULL); 
        }
        
        Role currentRole = roleReadMapper.selectByPrimaryKey(currentUserId);
        if(null==currentRole){
            throw LandseaException.createException(LandseaErrorMessageEnum.ROLE_IS_NULL); 
        }
        String currentCode = currentRole.getCode();   //获取当前卡点角色名
        Integer currentCodeIndex = leaderList.lastIndexOf(currentCode);
        
        int nextCodeIndex = 0;
        if((currentCodeIndex+1)==leaderList.size()){  //说明最后一个人已经审批了,审批结束
            refund.setStatus(SystemCodeEnum.REFUND_STATUS_OVER.getCode());
            refund.setCurrentRoleId(-1);
            refund.setRefundDate(new Date());
            refundWriteMapper.updateByPrimaryKeySelective(refund);
            //退款类型非强行退房给租客发短信
            if(!refund.getRefundType().equals(RefundTypeEnum._RFDTYPE3.getCode())){
                if(!StringUtils.isEmpty(renterGender)){
                    Code code = codeService.getCode(renterGender);
                    if (code != null) {
                        //renterGender = code.getCodeDescTr(); 注释掉短信中的女士或先生
                        renterGender = "";
                    }
                }
                HashMap<String,Object> map = new HashMap<String,Object>();
                map.put("name", null==renterName?"":renterName);
                map.put("gender", null==renterGender?"":renterGender);
                map.put("money", null==refund.getRefundAmount()? 0 :refund.getRefundAmount());
                String codenumber = refund.getCardNo();
                map.put("fourlastnumber", codenumber.substring(codenumber.length()-4));
                String bank = refund.getBankName();
                map.put("bank", bank);
                sentMesgToRenter(renterPhone,map);
            }
            //修改账单
            billService.billCuteAfterConfirm(refund);
        }else{                                        //尚未审批结束
            nextCodeIndex = currentCodeIndex + 1;
            String nextCode = leaderList.get(nextCodeIndex);
            Role nextRole = roleReadMapper.getRoleByCode(nextCode);
            refund.setCurrentRoleId(nextRole.getId());
            refund.setStatus(nextRole.getCode());
            refundWriteMapper.updateByPrimaryKeySelective(refund);
            //发短信给下一角色
            List<PersonInfoDTO> pinfoList = refundReadMapper.getPersonInfoByPrjAndRole(projectId , nextRole.getCode());
            //发送消息
            HashMap<String,String> map = new HashMap<String,String>();
            map.put("refundCode", refund.getRefundCode());
            try{
                sentMag(pinfoList,map);
            }catch (Exception e){
                LOG.error("confirmRefund send msg error:"+e);
            }
        }
        
        //添加确认日志
        refundlog.setCheckDate(new Date());
        refundlog.setUserId(SecurityUtils.getCurrentLogin().getUserId());
        refundlog.setRoleId(currentUserId);
        refundLogWriteMapper.insertSelective(refundlog);
        
        result.put("status", 0);
        return result;
    }

    private void validateRefundLogParams(RefundLog refundlog)
    {
        
    }

    //通过项目和角色进行判断当前用户的操作权限
    private void validateCurrentLoginId(Refund refund) throws LandseaException
    {
        Integer userId = SecurityUtils.getCurrentLogin().getUserId();
        //获取当前用户权限下的项目【根据此，查询权限下的退款记录】
        UserPrjRoleDTO dto = userReadMapper.getPrjsAndRole(userId);
        List<UserProject> uplist = dto.getUserProject();        //用户管理的项目List
        List<Integer> prjIdlist = new ArrayList<Integer>();     //用户管理的项目id List
        for(UserProject up: uplist){
            prjIdlist.add(up.getPrjId());
        }
        Integer refundPrjId = refund.getPrjId();
        if(prjIdlist.contains(refundPrjId)){ //说明有项目权限
            
            List<UserRoleDTO> roledto = dto.getUserRole();          //自身角色list
            Integer currentUserId = refund.getCurrentRoleId();      //获取当前卡点角色的id
            List<Integer> selfRoleIdList = new ArrayList<Integer>();    //自身角色id list
            for(UserRoleDTO userroledto: roledto){
                selfRoleIdList.add(userroledto.getRoleId());
            }
            if(!selfRoleIdList.contains(currentUserId)){
                throw LandseaException.createException(LandseaErrorMessageEnum.NO_AUTHORITY); 
            }
        }else{
            throw LandseaException.createException(LandseaErrorMessageEnum.NO_AUTHORITY); 
        }
    }

    @Override
    public List<RefundLogDTO> confirmRecord(Integer refundId)
    {
        List<RefundLogDTO> logdto = refundLogReadMapper.getRefundLogByRefundId(refundId);
        
        return logdto;
    }

    @Override
    public boolean checkApplyRefund(Integer objectId, Integer objectType) throws LandseaException {
        Refund refund = new Refund();
        refund.setObjectId(objectId);
        refund.setType(objectType);
        return exiteOffRent(refund);
    }

    @Override
    public Integer createContact(OffrentContactDTO dto) throws LandseaException {
        if(dto.getContractId()==null || dto.getContractId()==0){
            throw LandseaException.createException(LandseaErrorMessageEnum.CONTRACTID_IS_NULL);
        }
        if(StringUtils.isEmpty(dto.getContactTime())){
            throw LandseaException.createException(LandseaErrorMessageEnum.REFUND_CONTACT_DATE_IS_NULL);
        }
        if(StringUtils.isEmpty(dto.getChannel())){
            throw LandseaException.createException(LandseaErrorMessageEnum.REFUND_CONTACT_CHANEL_IS_NULL);
        }
        OffrentContact oc = new OffrentContact();
        Integer userId = SecurityUtils.getCurrentLogin().getUserId();
        oc.setContractId(dto.getContractId());
        oc.setContactTime(DateUtil.getInstence().convertDate(dto.getContactTime()));
        oc.setChannel(dto.getChannel());
        oc.setComment(dto.getComment());
        oc.setFileIds(dto.getFileIds());
        oc.setUserId(userId);
        oc.updateCommonInfo(userId);
        offrentContactWriteMapper.insertSelective(oc);
        return oc.getId();
    }

    @Override
    public List<OffrentContactDTO> queryContactByContractId(Integer contractId) throws LandseaException{
        if(contractId==null || contractId==0){
            throw LandseaException.createException(LandseaErrorMessageEnum.CONTRACTID_IS_NULL);
        }
        List<OffrentContactDTO> ocList = offrentContactReadMapper.queryByContractId(contractId);
        if(ocList!=null){
            try {
                for(OffrentContactDTO oc:ocList){
                    if(!StringUtils.isEmpty(oc.getFileIds())){
                        String[] files = oc.getFileIds().split(",");
                        List<String> filePaths = new ArrayList<>();
                        for(String fileId:files){
                            SystemFile img = (SystemFile)fileService.get(Integer.parseInt(fileId));
                            filePaths.add(img.getFullPath());
                        }
                        oc.setFilePaths(filePaths);
                    }
                }
            } catch (BusinessException e) {
               LOG.error("queryContactByContractId query file error:"+e);
            }
        }
        return ocList;
    }
    
    public List<Role> getStatusRole()
    {
        //获取审批角色的所有id
        if(null==leaderRoleList){
            leaderRoleList = roleReadMapper.getRoleByCodeList(leaderList); 
        }
        
        Map<String,Role> map = new HashMap<String,Role>();
        for (Role role : leaderRoleList)
        {
            map.put(role.getCode(), role);
        }
        
        List<Role> returnList = new ArrayList<Role>();
        for (String roleCode : leaderList)
        {
            returnList.add(map.get(roleCode));
        }
        
        return returnList;
    }

	@Override
	public Map<String, Object> printRefundReceipt(Integer refundId) throws LandseaException 
	{
		Map<String, Object> resultData = new HashMap<String, Object>();
		//退款详情
		QueryUtil queryUtil = new QueryUtil();
		PagingTool pagingTool = new PagingTool();
		pagingTool.setCurrentPage(0);
		pagingTool.setPageSize(-1);
		queryUtil.setPagingTool(pagingTool);
		List<QueryCriteria> queryCriterias = new ArrayList<QueryCriteria>();
		QueryCriteria e = new QueryCriteria();
		e.setCondition("=");
		e.setConnection("and");
		e.setIsValueADigital(false);
		e.setKey("id");
		e.setValue(refundId+"");
		queryCriterias.add(e);
		queryUtil.setQueryCriterias(queryCriterias);
		List<RefundDTO> refundDTOs = getRefundList(queryUtil);
		resultData.put("refundDetail", refundDTOs);
		
		//退款金额详情
		Integer objectId = refundDTOs.get(0).getObjectId();
		Integer type = refundDTOs.get(0).getType();
		if (null != type) 
		{
			if (1 == type.intValue()) 
			{
				PreBillResp resp = new PreBillResp();
				resp.setRefundAmount(-refundDTOs.get(0).getRefundAmount());
				resp.setLastHourseDate(DateUtil.convertDateTime(refundDTOs.get(0).getApplyDate()));
				resultData.put("moneyDetail", resp);
			}
			else
			{
				Object obj = offRent.queryPreBill(objectId,LandeaConstants.OffRentBillType.OFFRENTBILL);
				resultData.put("moneyDetail", obj);
			}
			resultData.put("refundType", refundDTOs.get(0).	getType());
		}
		
		
		
		//审批记录
		List<RefundLogDTO> refundLogDTOs = confirmRecord(refundId);
		resultData.put("approvalRecord", refundLogDTOs);
		
		//打印时间
		String time = DateUtil.convertDateTime(new Date());
		resultData.put("printTime", time);
		//打印人
		UserDTO dto = userReadMapper.getUserDTO(SecurityUtils.getCurrentLogin().getUserId()+"");
		resultData.put("printPeople", dto.getFull_name());
		return resultData;
	}
}
